package com.bang.daybreak.common.util;

import com.bang.daybreak.common.enums.ErrorCodeEnum;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.Map;

/**
 * <p>
 * JWT token 生成工具类
 * </p>
 *
 * @author wangdejian
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public abstract class JWTUtils {

    /**
     * token秘钥，请勿泄露，请勿随便修改
     */
    private static final String SECRET = "jwtdaybreak";
    private static final String ISS = "echisan";

    /**
     * 过期时间是3600秒，既是1个小时
     */
    private static final long EXPIRATION = 3600L;

    /**
     * 选择了记住我之后的过期时间为7天
     */
    private static final long EXPIRATION_REMEMBER_ME = 604800L;


    /**
     * 生成token
     *
     * @param claims claims
     * @return
     */
    public static String createToken(Map<String, Object> claims) {
        // JWT是由头部、载荷与签名组成
        return Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .setIssuer(ISS)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_REMEMBER_ME * 1000))
                .compact();
    }

    /**
     * 解析Claims
     *
     * @param token token
     * @return
     */
    public static Claims getClaim(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            ApiAssert.failure(ErrorCodeEnum.UNAUTHORIZED);
        }
        return claims;
    }

    /**
     * 获取jwt发布时间
     */
    public static Date getIssuedAt(String token) {
        return getClaim(token).getIssuedAt();
    }

    /**
     * 获取用户uuid.
     */
    public static String getUserId(String token) {
        return getTokenBody(token).getSubject();
    }

    /**
     * @param token token
     * @return
     */
    private static Claims getTokenBody(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
    }


    /**
     * 验证token是否失效
     *
     * @param token
     * @return true:过期   false:没过期
     */
    public static boolean isExpired(String token) {
        try {
            final Date expiration = getExpiration(token);
            return expiration.before(new Date());
        } catch (ExpiredJwtException expiredJwtException) {
            return true;
        }
    }

    /**
     * 获取jwt失效时间
     */
    public static Date getExpiration(String token) {
        return getClaim(token).getExpiration();
    }

}
